﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TestXNA3.Render;

namespace TestXNA3.Resources
{
    public abstract class ShaderResource : Resource
    {
        // Same for every effect
        protected Matrix _view;
        protected Matrix _projection;
        protected Matrix _world;

        // Eye position
        protected Vector4 _eyePosition = Vector4.Zero;

        public Effect Effect = null;

        [System.ComponentModel.Browsable(false)]
        public Matrix View
        {
            set { SetViewMatrix(value); }
        }
        [System.ComponentModel.Browsable(false)]
        public Matrix Projection
        {
            set { SetProjectionMatrix(value); }
        }
        [System.ComponentModel.Browsable(false)]
        public Matrix World
        {
            set { SetWorldMatrix(value); }
        }

        [System.ComponentModel.Browsable(false)]
        public Vector4 EyePosition
        {
            set { _eyePosition = value; }
        }

        protected virtual void SetViewMatrix(Matrix view)
        {
            _view = view;
        }
        protected virtual void SetProjectionMatrix(Matrix projection)
        {
            _projection = projection;
        }
        protected virtual void SetWorldMatrix(Matrix world)
        {
            _world = world;
        }

        protected EffectTechnique _defaultTechnique = null;
        public abstract void SetTechnique(SceneRenderer.EDrawMode drawMode);
        public void RestoreDefaultTechnique()
        {
            if (Effect != null)
            {
                if (_defaultTechnique == null)
                    throw new Exception("Default technique not set");

                Effect.CurrentTechnique = _defaultTechnique;                
            }
        }

        // Shader process
        public abstract void ApplyShaderConst();

        // Same for most of shaders
        public virtual int GetPassCount()
        {
            return Effect.CurrentTechnique.Passes.Count;
        }
        public virtual void Begin()
        {
            Effect.Begin();
        }
        public virtual void BeginPass(int pass)
        {
            Effect.CurrentTechnique.Passes[pass].Begin();
        }
        public virtual void EndPass(int pass)
        {
            Effect.CurrentTechnique.Passes[pass].End();
        }
        public virtual void End()
        {
            Effect.End();
        }


        // Save/load
        public abstract void Save(System.IO.BinaryWriter writer);
        public abstract void Load(System.IO.BinaryReader reader);
        public abstract void DuplicateProperties(ShaderResource to);
    }
}
